library theme;

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:xbaistack/provider/theme_provider.dart';

import 'package:xbaistack/utils/helper.dart';

part 'theme.dart';
part 'theme_data.dart';

final class AppTheme extends _ThemeData<AppTheme> {
  // 当前自定义的主题数据
  late final ThemeData data;

  // 主题数据中的颜色数据
  // 单独提取出来的话，在使用的时候不需要通过 data 再去调一次，算是冗余数据吧
  late final ColorScheme scheme;

  // 指定当前的颜色亮度
  final Brightness _brightness;

  // 为了应对频繁的创建主题对象
  // 所以，此处加入了缓存机制
  // 这样，在多次创建同一个主题的情况下，可以重复利用之前创建的对象
  static final Map<Brightness, AppTheme> _cached = {};

  // 私有化构造函数
  // 由于不需要让外部直接去构造，所以不需要做成公开的
  AppTheme._({
    required Brightness brightness,
    required Map<String, dynamic> defines,
  }) : _brightness = brightness,
       super(defines) {
    // 延迟初始化
    // 因为需要将自定义的主题样式扩展到 ThemeData 中，所以需要延迟创建
    data = _createThemeOf(); // 注：这个方法后面才会加入
    // 冗余数据，方便外部直接获取
    scheme = data.colorScheme;
  }

  /// 深色主题模式
  factory AppTheme.dark() {
    return _cached.putIfAbsent(
      Brightness.dark,
      () => AppTheme._(brightness: Brightness.dark, defines: _darkThemes_),
    );
  }

  /// 亮色主题模式
  factory AppTheme.light() {
    return _cached.putIfAbsent(
      Brightness.light,
      () => AppTheme._(brightness: Brightness.light, defines: _lightThemes_),
    );
  }

  @override
  ThemeExtension<AppTheme> copyWith() {
    return AppTheme._(brightness: _brightness, defines: _defines);
  }

  @override
  ThemeExtension<AppTheme> lerp(covariant AppTheme? other, double t) {
    if (other is! AppTheme) return this;
    return AppTheme._(brightness: other._brightness, defines: other._defines);
  }

  /// 提供一个类似于 Theme.of(context) 的获取方法
  static AppTheme of(BuildContext context) {
    try {
      final theme = Theme.of(context).extension<AppTheme>();
      return theme ?? context.read<ThemeProvider>().currentOf(context);
    } catch (e) {
      return AppTheme.light();
    }
  }

  /// 创建自定义的主题数据
  /// 需要在方法中融入自定义的主题数据
  ThemeData _createThemeOf() {
    final isDark = _brightness == Brightness.dark;
    final schema = isDark
        ? const ColorScheme.dark()
        : const ColorScheme.light();
    return ThemeData(
      // 当前主题的颜色模式（Brightness.dark | Brightness.light）
      brightness: _brightness,

      // 核心要点，必须要将自定义的 [AppTheme] 放进来
      // 否则无法通过 Theme.of(context).extension<AppTheme>() 获取
      extensions: [this],

      // 去掉水波纹点击效果
      // 如果需要保留的话，不写这两行就可以了
      splashColor: Colors.transparent,
      highlightColor: Colors.transparent,

      // 各种颜色值自定义
      colorScheme: schema.copyWith(
        // 底层背景颜色
        surface: backgroundColor,
        // 直接在背景之上显示的颜色（文本/图标之类）
        onSurface: textColor,
        // 背景之上容器的颜色
        surfaceContainer: appBarColor,

        // 主色调
        primary: themeColor,
        onPrimary: textColor,

        // 次级背景颜色
        secondary: secondaryColor,
        // 次级背景之上显示的颜色（文本/图标之类）
        onSecondary: onSecondaryColor,
        // 次级背景之上容器的颜色
        secondaryContainer: secondaryContainer,
      ),

      // 字体图标样式
      iconTheme: IconThemeData(color: textColor),

      // TabBar 样式
      tabBarTheme: const TabBarThemeData(),

      // 分割线样式
      dividerTheme: DividerThemeData(color: borderColor),

      // 滚动条样式
      scrollbarTheme: const ScrollbarThemeData(),

      // 角标样式
      badgeTheme: BadgeThemeData(textColor: textColor),

      // 抽屉菜单样式
      drawerTheme: DrawerThemeData(backgroundColor: drawerBackgroundColor),

      // 顶部导航条样式
      appBarTheme: AppBarTheme(
        elevation: 0,
        centerTitle: true,
        scrolledUnderElevation: 0.5,
        shadowColor: borderColor,
        foregroundColor: textColor,
        backgroundColor: WidgetStateColor.resolveWith((states) {
          return states.contains(WidgetState.scrolledUnder)
              ? appBarColor
              : backgroundColor;
        }),
      ),

      // 底部导航栏的样式
      bottomNavigationBarTheme: BottomNavigationBarThemeData(
        elevation: 0.5,
        selectedItemColor: themeColor,
        backgroundColor: bottomAppBarColor,
        type: BottomNavigationBarType.fixed,
        selectedIconTheme: const IconThemeData(size: 20),
        unselectedIconTheme: const IconThemeData(size: 20),
        selectedLabelStyle: const TextStyle(fontSize: 12),
        unselectedLabelStyle: const TextStyle(fontSize: 12),
        enableFeedback: true,
      ),

      // 页面过渡效果主题样式
      pageTransitionsTheme: const PageTransitionsTheme(
        builders: {
          TargetPlatform.android: CupertinoPageTransitionsBuilder(),
          TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
          TargetPlatform.windows: CupertinoPageTransitionsBuilder(),
        },
      ),
    );
  }
}
